#include "fileperf.hh"

#include "iNode_fs.h"
#include "FAT_fs.h"

#define EXIT_ERR -1
#define EXIT_SUCCESS 0

#ifndef NULL
#define NULL (0)
#endif


/*
 * blockSize: 	The size of a single block on disk.
 * pointerSize: The size of one pointer to a block on disk.
 * maximalSize: The size of the largest file this storage method needs to support.
 * type: 		The type of file storage to use.
 * fileSizes: 	The sizes of all the files that should be 'stored' on disk.
 *
 * returns 0 on success, -1 on failure. Fills 'output' with results.
 */
int fileSystemPerformance(unsigned int blockSize,
						  unsigned int pointerSize,
			  	  	  	  unsigned int maximalSize,
			  	  	  	  storageType type,
			  	  	  	  const std::vector<unsigned int> fileSizes,
			  	  	  	  outputStruct *output)
{
	result_t result;
	int res = EXIT_SUCCESS;

	// validate arguments
	if( NULL == output || pointerSize > blockSize )
	{
		return EXIT_ERR;
	}

	if (  ! pointerSize || ! blockSize || ! maximalSize )
	{
		return EXIT_ERR;
	}

	if ( fileSizes.empty() )
	{
		return EXIT_ERR;
	}

	FileSystem *fs = NULL;

	switch(type) {

	case FS_INODE:
		fs = new iNode_fs(blockSize, pointerSize, maximalSize, result);
		break;

	case FS_LINKED_LIST:
		fs = new FAT_fs(blockSize, pointerSize, maximalSize, result);
		break;

	default:
		ERR_PRINT("Unknown FS type\n");
		return EXIT_ERR;
	}

	if ( OPERATION_SUCCESS != result )
	{
		ERR_PRINT("Creation of FS object failed with result = %d!\n", result);
		res = EXIT_ERR;
		goto cleanups;
	}

	result = fs->calc_performance( fileSizes, output );
	if ( OPERATION_SUCCESS != result )
	{
		ERR_PRINT("calc_performance() failed with result = %d!\n", result);
		res = EXIT_ERR;
		goto cleanups;
	}



cleanups:

	if ( NULL != fs )
	{
		delete fs;
		fs = NULL;
	}

	return res;

}
